home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Threading Functions
- */
-
- #include "include/config.h"
-
- #include <stdlib.h>
- #include <string.h>
-
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <dos/dostags.h>
-
- #include "include/thread.h"
-
- struct MsgPort *th_mother=NULL;
- thread th_list=NULL;
- u_long th_sigmask=0;
-
- void th_handlemsg(thmsg m);
- void th_cleanup(thread t);
-
-
- int th_lala(void)
- {
- th_mother = CreateMsgPort();
- if (!th_mother) return(0);
- th_sigmask = 1L << (th_mother->mp_SigBit);
- return(1);
- }
-
-
- void th_bibi(void)
- {
- thread t;
-
- t = th_list;
- while (t) {
- th_message(t,THC_EXIT,0);
- t = t->next;
- }
-
- while (th_list) {
- thmsg m;
- WaitPort(th_mother);
- m = (thmsg)GetMsg(th_mother);
- th_handlemsg(m);
- }
-
- DeleteMsgPort(th_mother);
- th_sigmask = 0;
- }
-
-
- thread th_spawn(thcb handler, char *name, void (*func)(void), int pri, APTR data)
- {
- thread t;
-
- t = malloc(sizeof(_thread));
- if (!t) return(NULL);
- memset(t,0,sizeof(_thread));
-
- t->task = (struct Task *)CreateNewProcTags(
- NP_Entry, func,
- NP_Name, name,
- NP_StackSize, 8192,
- NP_Priority, pri,
- TAG_DONE);
-
- if (!t->task) {
- free(t);
- return(NULL);
- }
-
- t->handler = handler;
- t->mother = th_mother;
- t->data = data;
-
- t->sm.header.mn_ReplyPort = th_mother;
- t->sm.header.mn_Length = sizeof(_thmsg);
- t->sm.com = THC_STARTUP;
- t->sm.data = t;
-
- /* Begin new stuff */
- t->task->tc_UserData = &t->sm;
- t->mother_task = FindTask(NULL);
- SetSignal(0L, SIGF_SINGLE);
- Signal(t->task, SIGF_SINGLE);
- Wait(SIGF_SINGLE);
- /* End new stuff */
-
- /* Old stuff
- PutMsg(&((struct Process *)t->task)->pr_MsgPort,(struct Message *)&t->sm);
- End old stuff */
-
- /* Begin new stuff */
- if(handler) (handler)(t,THC_STARTUP,data);
- /* End new stuff */
-
- t->next = th_list;
- th_list = t;
- return(t);
- }
-
-
- void th_message(thread t, int com, APTR data)
- {
- thmsg m;
-
- if(!t) return;
- if(!t->port) return;
-
- m = malloc(sizeof(_thmsg));
- if(!m) return;
- memset(m,0,sizeof(_thmsg));
-
- m->header.mn_ReplyPort = th_mother;
- m->header.mn_Length = sizeof(_thmsg);
- m->com = com;
- m->data = data;
-
- PutMsg(t->port,(struct Message *)m);
- }
-
-
- void th_poll(void)
- {
- thread t;
- thmsg m;
-
- while(1) {
- m = (thmsg)GetMsg(th_mother);
- if(!m) break;
-
- if(m->com != THC_FINISH && (!m->isreply)) {
- t = m->sender;
- if(t && t->handler)
- (t->handler)(t,m->com,m->data);
- }
-
- th_handlemsg(m);
- }
- }
-
-
- thread thr_init(void)
- {
- thread t;
- thmsg m;
- struct Task *me = FindTask(NULL);
-
- /* Begin new stuff */
- Wait(SIGF_SINGLE);
- m = (thmsg)me->tc_UserData;
- t = (thread)m->data;
-
- t->port = CreateMsgPort();
- if(!t->port) {
- me->tc_UserData = (APTR)FALSE;
- t = NULL;
- }
- else {
- me->tc_UserData = (APTR)TRUE;
- m->sender = t;
- }
- Signal(t->mother_task, SIGF_SINGLE);
- /* End new stuff */
-
- /* Begin old stuff
- WaitPort(&((struct Process *)me)->pr_MsgPort);
- m = (thmsg)GetMsg(&((struct Process *)me)->pr_MsgPort);
- t = m->data;
-
- t->port = CreateMsgPort();
- if(!t->port) return(NULL);
-
- m->sender = t;
- ReplyMsg((struct Message *)m);
- End old stuff */
-
- return(t);
- }
-
-
- void thr_exit(thread t, int reason)
- {
- t->em.header.mn_ReplyPort = t->port;
- t->em.header.mn_Length = sizeof(_thmsg);
- t->em.com = THC_EXIT;
- t->em.data = (APTR)reason;
- t->em.sender = t;
- PutMsg(t->mother,(struct Message *)&t->em);
-
- while(1) {
- thmsg m;
- WaitPort(t->port);
- m = (thmsg)GetMsg(t->port);
- if(&t->em == m) break;
- m->isreply = 1;
- ReplyMsg((struct Message *)m);
- }
-
- Forbid();
- t->em.sender = t;
- t->em.com = THC_FINISH;
- PutMsg(t->mother,(struct Message *)&t->em);
-
- if(t->port) DeleteMsgPort(t->port);
- }
-
-
- void thr_message(thread t, int com, APTR data)
- {
- thmsg m;
-
- m = malloc(sizeof(_thmsg));
- if(!m) return;
- memset(m,0,sizeof(_thmsg));
-
- m->header.mn_ReplyPort = t->port;
- m->header.mn_Length = sizeof(_thmsg);
- m->sender = t;
- m->com = com;
- m->data = data;
-
- PutMsg(t->mother,(struct Message *)m);
- }
-
-
- /* private functions */
-
- void th_handlemsg(thmsg m)
- {
- if(m->com==THC_STARTUP) return;
-
- if(m->com==THC_FINISH) {
- th_cleanup(m->sender);
- } else {
- if(m->isreply) {
- free(m);
- } else {
- m->isreply = 1;
- ReplyMsg((struct Message *)m);
- }
- }
- }
-
-
- void th_cleanup(thread t)
- {
- if(th_list==t) {
- th_list = t->next;
- } else {
- thread tmp = th_list;
- while(tmp) {
- if(tmp->next==t) {
- tmp->next=t->next;
- break;
- }
- tmp = tmp->next;
- }
- }
- free(t);
- }
-